home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************/
- /* C_LINES.C */
- /********************************************************************/
- /* 1986 by David Archibald. CIS 73256,2640 */
- /* Released to the public domain on Dec. 6, 1986. */
- /* */
- /* This program is compatible with both Alcyon and Megamax. */
- /*------------------------------------------------------------------*/
- /* This program adds line numbers to a C text file, and then sends */
- /* the file to the screen, printer or a disk file. */
- /* */
- /*------------------------------------------------------------------*/
- /* The command line reads: */
- /* A:inputFile [B:outputFile] [-a] [-s] [-p] [-h] [-f {xx}] */
- /* [-t {x}] [-c] [-b {xxxxx}] */
- /*------------------------------------------------------------------*/
- /* All of the commands, and any numbers that follow them, must be */
- /* separated on the command line by a space. All the commands that */
- /* are inclosed by brackets, are optional. */
- /*------------------------------------------------------------------*/
- /* inputFile - is the C text file name. It must be the 1st command */
- /* on the command line. */
- /* */
- /* outputFile - is the file name that the output from the -a and -s */
- /* is sent to. A file name is required with either of */
- /* these commands, and it must be the 1st item */
- /* following the inputFile name, on the command line. */
- /*__________________________________________________________________*/
- /* the use of a RAM disk with these two commands, is *highly* */
- /* recommended. */
- /*------------------------------------------------------------------*/
- /* -a - adds line numbers to each line, and then save it to */
- /* the outputFile. */
- /* */
- /* -s - strips the line numbers from a inputFile that was */
- /* previously created, by using the '-a' command. */
- /*------------------------------------------------------------------*/
- /* All of the following commands are ignored, when the -a or -s */
- /* commands are chosen. */
- /*------------------------------------------------------------------*/
- /* These two commands work with both screen or printer output. */
- /*------------------------------------------------------------------*/
- /* */
- /* -c - truncates the output line whenever it's length */
- /* exceeds 80 characters (counting the line number). */
- /* This command works with both screen or printer output*/
- /* */
- /* -b - skips 'x' amount of inputFile's lines. Does not print*/
- /* any lines, until the line number that follows -b on */
- /* the command is reached. This command does not have */
- /* default line number. If no line number is entered, */
- /* then the program will begin printing at line 1. */
- /*------------------------------------------------------------------*/
- /* */
- /* -p - sends the text file to the printer. If a wrap-around */
- /* occurs, the text on the 2nd line is indented, so */
- /* that it starts on the same column as the 1st line */
- /* (it takes into account the line number). */
- /* */
- /*------------------------------------------------------------------*/
- /* the following commands are ignored, unless the output is sent */
- /* to the printer. */
- /*------------------------------------------------------------------*/
- /* */
- /* -h - sends a header to the printer. The header consists */
- /* of 6 lines. The 1st two are blank, the 3rd is the */
- /* name of the file being listed, the 4th is the page */
- /* number and the time (24 hour clock) & date of */
- /* printing, and the 5th and 6th are blank. */
- /* */
- /* -f - prints 'x' amount of blank lines at the bottom of the*/
- /* page to skip over the perf. The the number of blank */
- /* lines is entered on the command line, after the -f */
- /* command. The maximum number is 6 lines. If there is */
- /* no number, then the footer defaults to 3 lines. */
- /* */
- /* -t - Tabs the printout over a user defined amount of */
- /* up to 15 spaces. If no number follows the -t command,*/
- /* then the tab defaults to 6 spaces. */
- /* */
- /*------------------------------------------------------------------*/
- /* If you enter only a input file name, the defaults are: */
- /* */
- /* output to the screen, no header, no tab, no truncate, no footer, */
- /* and start output at line number 1. */
- /*------------------------------------------------------------------*/
- /* These commands work whether the file is going to the, disk */
- /* printer or screen: */
- /* pressing 'Q' exits the program. */
- /* pressing 'p' pauses the program, and */
- /* any other key restarts it. */
- /* */
- /********************************************************************/
- /* I M P O R T A N T N O T E ! ! ! ! */
- /* */
- /* If you are going to compile this program with Alcyon, you must */
- /* enlarge the STACK size in the "Gemstart" link file, otherwise */
- /* the stack will overflow and start to overwrite the programs */
- /* variables (I changed the stack size from 1K to 3K). If you are */
- /* using Megamax, just ignore this. */
- /********************************************************************/
-
-
- #include <stdio.h>
- #include <osbind.h>
- #include <string.h>
-
- #define EMPTY 0
- #define CONT 1
- #define QUIT 0
- #define ON 1
- #define TOLOWER(c) ((c)>='A' && (c)<='Z' ? (c)+=32:(c))
- /* Alcyon doesn't have this and we need it with Megamax. */
-
- typedef int VOID; /* needed only with Megamax */
-
- struct cm {
- int strip;
- int add;
- int print;
- int header;
- int footer;
- int foot_amt;
- int tab;
- int tab_amt;
- int line_num;
- int prt_cnt;
- int page_no;
- int trun;
- int begin;
- int start_ln;
- };
-
- /* ------------global variables: for input & output files------------ */
-
- FILE *fp_in;
- FILE *fp_out;
- FILE *fopen(); /* needed only with Alcyon */
-
- main (argc,argv)
- int argc;
- char *argv[];
-
- {
- int flag=CONT, t, esc=0x011b;
- char str_in[255];
- static struct cm command={0};
-
-
- Cconout(esc); /* turn cursor off (it looks better*/
- Cconout('f'); /* when outputing with it off.) */
-
- Cconout(esc); /* clear the screen. */
- Cconout('E');
-
- parse_cmd(argv,&command,argc); /* get commands entered */
-
- flag=open_input(argv,argc); /* open input C file */
-
- if ((command.add==ON || command.strip==ON) && flag==CONT)
- flag=open_out(argv); /* open output file */
-
- while(flag==CONT)
- {
- flag=keypress(); /* check for keypress */
- if (flag==QUIT) break;
-
- /*____________________________________________________________________*/
- /* read line from input file. flag=0 if EOF reached. */
- /*--------------------------------------------------------------------*/
- flag=get_str(str_in);
-
- /*____________________________________________________________________*/
- /* after the last line has been read, wait for keypress before */
- /* returning to the desktop or the command mode. */
- /*--------------------------------------------------------------------*/
- if (flag==QUIT)
- {
- pause(); /* wait until key is pressed */
- break;
- }
-
- /*____________________________________________________________________*/
- /* if you don't want to start at the 1st line in the file then loop */
- /* until the line number that was entered is reached. */
- /*--------------------------------------------------------------------*/
- if (command.begin==ON && command.line_num+1<command.start_ln)
- {
- skip_lines(&command);
- continue; /* skip other commands. */
- }
-
- /*____________________________________________________________________*/
- /* strip line number off input line & write to output file */
- /*--------------------------------------------------------------------*/
- else if (command.strip==ON)
- {
- strip_num(str_in);
- continue; /* skip other commands. */
- }
-
- /*____________________________________________________________________*/
- /* add line number to line & write to output file */
- /*--------------------------------------------------------------------*/
- else if (command.add==ON)
- {
- add_num(str_in, &command);
- continue; /* once again--don't check for cmd */
- }
-
- /*____________________________________________________________________*/
- /* send line to printer */
- /*--------------------------------------------------------------------*/
- else if (command.print==ON)
- flag=printer(str_in, &command, argv);
-
- /*____________________________________________________________________*/
- /* or send line to screen */
- /*--------------------------------------------------------------------*/
- else flag=prt_crt(str_in, &command);
- }
-
- Cconout(esc); /* turn cursor back on. */
- Cconout('e');
-
- if (fp_in!=0) fclose(fp_in);
- if (fp_out!=0) fclose(fp_out);
-
- }
-
-
- VOID parse_cmd(cmd_line, c, num)
- char *cmd_line[];
- struct cm *c;
- int num;
-
- {
- int t, amt;
-
- for (t=2;t<num;++t) /* loop 'til all commands checked */
- {
- if (cmd_line[t][0]!='-') /* don't treat 2nd file name */
- continue; /* as command, check for '-'.*/
-
- switch(TOLOWER(cmd_line[t][1])) /* if the command is upper-*/
- { /* case then make it lower.*/
- case 's':
- c->strip=ON; /* strip line #'s from input file */
- return(EMPTY); /* ignore all other commands */
-
- case 'a':
- c->add=ON; /* add line #'s to input file */
- return(EMPTY); /* ignore all other commands */
-
- case 'p':
- c->print=ON; /* send output to the printer */
- break; /* check for next command */
-
- case 'c':
- c->trun=ON; /* truncate output to screen */
- break; /* or prt past 80 characters. */
-
- case 'h':
- c->header=ON; /* print header to printer */
- break; /* check for next command */
-
- case 'f':
- c->footer=ON; /* print footer to printer */
-
- /*____________________________________________________________________*/
- /* check if the size of footer follows command */
- /*--------------------------------------------------------------------*/
- c->foot_amt=3; /* incase no size entered = default */
-
- if (t+1<num)
- {
- amt=atoi(cmd_line[t+1]); /* get number after '-f' */
- if (amt<0 || amt>6) /* make it fall in range */
- amt=6;
-
- if (amt!=0)
- {
- c->foot_amt=amt; /* if all ok, then equal input */
- ++t; /* move loop pointer past # */
- }
- }
- break; /* check for next command. */
-
-
- case 'b':
- c->begin=ON; /* skip lines. */
-
- /*____________________________________________________________________*/
- /* check for the line number to skip to */
- /*--------------------------------------------------------------------*/
-
- if (t+1<num)
- {
- amt=atoi(cmd_line[t+1]); /* get number after '-b' */
- if (amt<0) /* make it fall in range */
- amt=0; /* <0 then don't skip any. */
-
- if (amt!=0)
- {
- c->start_ln=amt; /* if all ok, then equal input */
- ++t; /* move loop pointer past # */
- }
- }
- break; /* check for next command. */
-
-
- case 't':
- c->tab=ON; /* tab to printer */
-
- /*____________________________________________________________________*/
- /* check if size of tab follows command */
- /*--------------------------------------------------------------------*/
- c->tab_amt=6; /* incase no size entered = default */
-
- if (t+1<num)
- {
- amt=atoi(cmd_line[t+1]); /* get number after '-t'. */
- if (amt<0 || amt>15) /* make it fall in range */
- amt=15;
-
- if (amt!=0)
- {
- c->tab_amt=amt; /* if all ok, equal input */
- ++t; /* move loop pointer past # */
- }
- }
- }
- }
- }
-
-
-
- keypress()
-
- {
- char ch;
-
- if (Cconis()<0) /* is there a character available? */
- {
- ch=Cnecin();
- if (ch=='p' || ch=='P') /* pause listing? */
- ch=Cnecin(); /* wait for keypress */
- if (ch=='q' || ch=='Q') return(QUIT); /* quit the program */
- }
- return(CONT);
- }
-
-
-
- open_input(cmd_line,num)
-
- int num;
- char *cmd_line[];
- {
- if (num>2 && cmd_line[2][0]!='-') /* are there 2 names for */
- /* strcmp to check. */
- if (strcmp(cmd_line[1],cmd_line[2])==0) /* check if input & */
- { /* output name are the same.*/
- printf("\n\nWHOA! both the input and");
- printf(" the output names are the same: %s\n",cmd_line[1]);
- pause();
- return(QUIT); /* exit the program.*/
- }
-
- fp_in=fopen(cmd_line[1],"r");
- if (fp_in==0)
- {
- printf("\nCannot open input file: %s \n",cmd_line[1]);
- pause();
- return(QUIT); /* set flag to 0 on return & exit prg. */
- }
-
- return(CONT);
- }
-
-
-
- open_out(cmd_line)
-
- char *cmd_line[];
- {
- if (cmd_line[2][0]!='-') /* don't use a command as */
- fp_out=fopen(cmd_line[2],"w"); /* the 2nd file name. */
-
- if (fp_out==0)
- {
- printf("\nCannot open output file: %s \n",cmd_line[2]);
- pause();
- return(QUIT); /* set 'flag' to 0 on return & exit program */
- }
-
- return(CONT);
- }
-
-
-
- get_str(line)
-
- char line[];
- {
-
- fgets(line,255,fp_in); /* read line from input file */
-
- if (line[0]=='\0')
- return(QUIT); /* when EOF then all done */
-
- else return(CONT);
- }
-
-
- /*____________________________________________________________________*/
- /* save input line back to output file minus */
- /* the line number at the start of line. */
- /*--------------------------------------------------------------------*/
-
- VOID strip_num(line)
-
- char line[];
- {
- int esc=0x011b;
-
- /*____________________________________________________________________*/
- /* check for line number at the start of the line-- incase a */
- /* new line was added to the file after the line numbers were added. */
- /*--------------------------------------------------------------------*/
-
- if (atoi(line)==0)
- {
- fputs(line,fp_out); /* if no line # then output the line*/
- return(EMPTY); /* without striping non-existent #. */
- }
-
- fputs(&line[8],fp_out); /* output line. */
- Cconout(esc); /* home the cursor. */
- Cconout('H');
- printf("\n\nStriping line number: %d\n",atoi(line));
-
- }
-
-
- /*____________________________________________________________________*/
- /* save input line to output file with line */
- /* numbers at the start of the line. */
- /*format of line is: 1 space, up to 5 numbers, 2 spaces, and the line.*/
- /*--------------------------------------------------------------------*/
-
- VOID add_num(line,c)
-
- char line[];
- struct cm *c;
- {
- int esc=0x011b;
-
- ++c->line_num;
- fprintf(fp_out,"%5d %s",c->line_num,line);
-
- Cconout(esc); /* home the cursor. */
- Cconout('H');
- printf("\n\nadding line number: %d\n",c->line_num);
-
-
- }
-
-
-
- printer(line,c,cmd_line)
-
- char line[], *cmd_line[];
- struct cm *c;
-
- {
- static int been_here=0;
- static char date[3][3], time[3][3];
- int t, t2, line_len, length, status, h_f_flag=0;
- char ch, num[9];
-
- /* the follow code checks if the printer is ready and gets the time & */
- /* date. It is only executed the 1st time this routine is called. */
-
- if (been_here==0)
- {
- ++been_here; /* pass this way never more */
-
- do
- {
- status=Cprnos(); /* is printer ready? status=1 if yes */
-
- if (status==0)
- {
- printf("\n\nPrinter is not ready. Press any key to ");
- printf("continue (Q to quit)\n");
- ch=Cnecin();
- if (ch=='q' || ch=='Q')
- return(QUIT); /* all done! exit program. */
- }
- }
- while (status==0); /* loop until printer is on or 'q' is entered*/
-
- time_date(date,time); /* get time & date */
- }
-
- /********************* end of one pass only code. *********************/
-
- h_f_flag=head_foot(c,cmd_line,date,time);
- /* check if time to print the header or footer */
-
- /*____________________________________________________________________*/
- /* if the tab flag is on then space the line over tab_amt to that col.*/
- /*--------------------------------------------------------------------*/
-
- if (c->tab==ON)
- for (t=0;c->tab_amt != t;++t)
- Cprnout(' ');
- /************************ end of tab section **************************/
-
- /*____________________________________________________________________*/
- /* let the horns sound! we finally print the line. well, almost... */
- /* first print the line number. */
- /*--------------------------------------------------------------------*/
-
- sprintf(num,"%5d ",++c->line_num); /* convert to ASCII.*/
- for (t=0;num[t]!='\0';++t)
- Cprnout(num[t]); /* print line number. */
-
- /*------------- now find out if the line will wrap around.------------*/
-
- line_len=79-(c->tab_amt+8); /* 79 line size, 8=line # + 2 space*/
- if (strlen(line)>line_len)
- {
- for (t=0;t != line_len && line[t]!='\0';++t)
- Cprnout(line[t]); /* stop printing after */
- /* reaching end of printer */
- /* line. */
-
- /*____________________________________________________________________*/
- /* call head_foot before printing the 2nd line so if a header or */
- /* is due to be printed, they will be. this way the header and footer */
- /* are kept in their correct place (i.e. not printed 1 line to late).*/
- /*--------------------------------------------------------------------*/
-
- if (line[t]!='\0' && c->trun!=ON) /* if not end-of-line and*/
- { /* truncate isn't 'on'...*/
- h_f_flag=head_foot(c,cmd_line,date,time);
-
- if (h_f_flag!=0) /* was head or foot performed? */
- Cprnout('\n'); /* if no - CR to 2nd line. */
-
- for (t2=c->tab_amt+9;t2!= 0;--t2) /* tab for wrap- */
- Cprnout(' '); /* around 2nd line. */
- /* tab amt + 9 for line #. */
- for (;line[t]!='\0';++t)
- Cprnout(line[t]); /* print the rest of the line*/
- }
- else Cprnout('\n'); /* truncate the line. */
- }
- else for (t=0;line[t]!='\0';++t) /* if no wrap-around then */
- Cprnout(line[t]); /* print the whole line. */
-
-
- return(CONT);
- }
-
-
-
- /**********************************************************************/
- /* TIME and DATE */
- /**********************************************************************/
- /* this routine load the system time and date and converts it into */
- /* ASCII characters. these characters are returned to the calling */
- /* routine in 2 arrays format so: time[3][3], date[3][3]. */
- /* ( "\0" goes in the 3rd cell of the array.) */
- /* */
- /* hours will be in: time[0][0], time[0][1] */
- /* minutes in : time[1][0], time[1][1] */
- /* seconds in : time[2][0], time[2][1] */
- /* */
- /* month will be in: date[0][0], date[0][1] */
- /* day in : date[1][0], date[1][1] */
- /* year in : date[2][0], date[2][1] */
- /**********************************************************************/
-
-
-
- VOID time_date(date,time)
-
- char date[][3], time[][3];
- {
- unsigned int work, date_time;
- int t;
-
- /* get date */
-
- date_time=Tgetdate();
- work=date_time & 31; /* mask all but lower 5 bits (day) */
- sprintf(&date[1][0],"%d",work);
- work=(date_time & 480)>>5; /* mask all but bits 5-8 (month) */
- sprintf(&date[0][0],"%d",work);
- work=(((date_time & 65024)>>9)+80);
- /* mask all but bits 9-15 (year+80)*/
- sprintf(&date[2][0],"%d",work);
-
- /* get time */
-
- date_time=Tgettime();
- work=(date_time & 31)*2; /* mask bits 0=4 (seconds * 2) */
- sprintf(&time[2][0],"%02d",work);
- work=(date_time & 2016)>>5; /* mask bits 5-10 (minutes) */
- sprintf(&time[1][0],"%02d",work);
- work=(date_time & 63488)>>11; /* mask bits 11-15 (hour) */
- sprintf(&time[0][0],"%02d",work);
-
- }
-
-
-
- prt_crt(line,c)
-
- char line[];
- struct cm *c;
- {
- int esc=0x011b;
- char ch;
- static int no_pause;
- /*____________________________________________________________________*/
- /* if 23 lines have been printed to the screen then wait for */
- /* keypress to continue. */
- /*--------------------------------------------------------------------*/
-
- if (++c->prt_cnt==23 && no_pause!=ON)
- {
- c->prt_cnt=0;
- printf("Press any key to continue (Q to quit--");
- printf("N to cancel this prompt line).\n");
- ch=Cnecin();
- if (ch=='q' || ch=='Q') return(QUIT);
- if (ch=='n' || ch=='N') no_pause=ON;
- }
- ++c->line_num; /* inc line number counter */
-
- Cconout(esc); /* turn on end of line wrap */
- Cconout('v');
-
- if (c->trun==ON && strlen(line) > 74) /* if truncate is 'on'*/
- printf("%5d %.73s\n",c->line_num,line);
- else
- printf("%5d %s",c->line_num,line); /* or print it all. */
-
-
- return(CONT);
- }
-
-
-
- VOID pause()
-
- {
- char ch;
-
- Cconws("\n All done. Press any key to exit.");
- ch=Cnecin();
-
- }
-
-
-
- head_foot(c,cmd_line,date,time)
-
- char date[][3],time[][3], *cmd_line[];
- struct cm *c;
-
- {
- static char page[]="page ", head_line[]=" Printed on: ";
- int t, name_len, h_f_flag=0;
- char ch, num[9], colon_slash;
-
-
- ++c->prt_cnt; /* keep track of what line the printer is on */
-
-
- /*____________________________________________________________________*/
- /* if skip over perf flag is on and the printers line cnt=66 - DO IT! */
- /*--------------------------------------------------------------------*/
-
- if (c->prt_cnt+c->foot_amt==67 && c->footer==ON)
- {
- for (t=c->foot_amt;t != 0;--t,++c->prt_cnt)
- Cprnout('\n');
- h_f_flag=ON; /* signal that footer was performed. */
- }
-
- /************************ end of footer section ***********************/
-
- if (c->prt_cnt>=66)
- c->prt_cnt=ON; /* re-set line counter */
-
-
- /*____________________________________________________________________*/
- /* if header flag is on and the printers line cnt=1 then print header */
- /*--------------------------------------------------------------------*/
-
- if (c->prt_cnt==1 && c->header==ON)
- {
- h_f_flag=ON; /* signal that header was performed. */
- Cprnout('\n'); /* print 2 blank lines */
- Cprnout('\n');
-
- /*____________________________________________________________________*/
- /* to center the input file's name on the 3rd line 1st get its length */
- /* then subtract it from 80 and then divide the remainder by 2. print */
- /* this number of spaces to the printer and then the file name. */
- /* Voila'! centered print. */
- /*--------------------------------------------------------------------*/
-
- name_len=strlen(cmd_line[1]); /* get len of file's name */
- name_len=80-name_len;
- if (name_len>0) /* if > 0 then file name */
- name_len /= 2; /* is < 80 char. in length*/
- else /* if < 0 then it's > 80 */
- { /* so don't try to center */
- name_len=0; /* it because it'll use 2 */
- c->prt_cnt+=1; /* lines anyways. (how you*/
- } /* will get 80 or more characters */
- /* on the cmd line, I do not know!*/
- /* but then you never know, so... */
- for (;name_len != 0;--name_len)
- Cprnout(' ');
- for (t=0;cmd_line[1][t]!='\0';++t) /* print file name */
- Cprnout(cmd_line[1][t]);
- Cprnout('\n');
-
-
- /*____________________________________________________________________*/
- /* print time, date and page number and then 2 blank lines. */
- /*--------------------------------------------------------------------*/
-
- for (t=0;head_line[t]!='\0';++t)
- Cprnout(head_line[t]); /* print 'Printed on:' */
-
- colon_slash='/';
- prt_t_d(date,colon_slash); /* print date with slash */
- Cprnout(' ');
-
- colon_slash=':';
- prt_t_d(time,colon_slash); /* print time with colon */
-
- for (t=0;t != 26;++t) /* print 26 spaces before*/
- Cprnout(' '); /* printing page number. */
-
- for (t=0;page[t]!='\0';++t)
- Cprnout(page[t]); /* print 'page' */
- sprintf(num,"%d",++c->page_no); /* convert int to ASCII */
- for (t=0;num[t]!='\0';++t)
- Cprnout(num[t]); /* print page number. */
-
- for (t=0;t!=3;++t) /* header takes up 6 lines.*/
- Cprnout('\n'); /* print 2 blank lines. */
-
- c->prt_cnt+=6; /* update prn line cnt. */
- }
-
- return(h_f_flag);
-
- }
-
-
-
- /*____________________________________________________________________*/
- /* prints the time and date to the printer */
- /* on entry 'colon_slash' equals a '/' when printing the date. it */
- /* separates the mm/dd/yy. 'colon_slash' equals a ':' when printing */
- /* the date. it separates the hh:mm:ss. */
- /*--------------------------------------------------------------------*/
-
- VOID prt_t_d(td,colon_slash)
-
- char td[][3],colon_slash;
- {
- int t, t2;
- char ch=' ';
-
- for (t=0;t!=3;++t)
- { /* print a space on the 1st pass */
- Cprnout(ch); /* so we don't get something */
- ch=colon_slash; /* like /mm/dd/yy or :hh:mm:ss*/
- for (t2=0;t2!=3;++t2)
- Cprnout(td[t][t2]);
- }
-
- }
-
-
- VOID skip_lines(c)
-
- struct cm *c;
-
- {
- int esc=0x011b;
-
- ++c->line_num;
-
- Cconout(esc); /* home the cursor. */
- Cconout('H');
- printf("\n\nreading line number: %d",c->line_num);
- printf(" but waiting for line: %d\n",c->start_ln);
-
-
- }
-
-